package com.alice.common.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.InputStream;
import java.util.concurrent.TimeUnit;

/**
 * 数据库操作类
 */
public class DbUtils {

    private static final Logger logger = LoggerFactory.getLogger(DbUtils.class);


    /**
     * host
     */
    public static final String host = "127.0.0.1";

    /**
     * database
     */
    public static final String database = "test";

    /**
     * username
     */
    public static final String username = "root";

    /**
     * password
     */
    public static final String password = "root";

    /**
     * 备份文件保存位置
     */
    public static final String backPath = "/data/backup/";

    /**
     * 备份文件命名规则
     */
    public static final String fileName = database + ".sql";

    /**
     * 备份工具绝对路径
     */
    public static final String toolPath = "/usr/local/mysql/bin/";

    public static String[] setCmd(){
        String[] cmd = new String[3];
        if (isLinuxSystem()){
            cmd[0]="/bin/sh";
            cmd[1]="-c";
        }else{
            //windows 运行多命令使用&隔开
            cmd[0]="cmd";
            cmd[1]="/c";
        }
        return cmd;
    }

    //判断系统是否是Linux
    public static boolean isLinuxSystem(){
        if(System.getProperty("os.name").toLowerCase().contains("linux")){
            return true;
        }
        return false;
    }

    /**
     * 备份操作工具
     */
    public static String dbBackUp() {

        // 备份文件名
        String finalFileName = DateUtils.formatDate() + "-" + fileName;
        //sql备份绝对路径
        String pathSql = backPath + finalFileName;
        StringBuilder backCmd = new StringBuilder();
        backCmd.append(toolPath + "mysqldump");
        backCmd.append(" -h" + host);
        backCmd.append(" -u" + username);
        backCmd.append(" -p" + password);
        backCmd.append(" --databases " + database + " > ");
        backCmd.append(pathSql);
        logger.info("待备份sql文件绝对路径:{}", pathSql);
        logger.info("待执行cmd命令:{}", backCmd.toString());
        logger.info("开始备份数据库:{} >>>>> ", database);
        String[] cmd = {"sh", "-c", backCmd.toString()};
        return exec(cmd);
    }

    private static String exec(String[] cmd) {
        try {
            Process process = Runtime.getRuntime().exec(cmd);
            boolean res = process.waitFor(20, TimeUnit.SECONDS);
            if (!res) {
                logger.info("执行time out");
                return "time out";
            }
            //todo: 输出字符串有乱码
            InputStream inputStream = process.getInputStream();
            byte[] data = new byte[1024];
            StringBuilder result = new StringBuilder();
            int len;
            while ((len = inputStream.read(data)) != -1) {
                result.append(new String(data, 0, len, "GBK"));
            }
            if (result.toString().equals("")) {
                InputStream errorStream = process.getErrorStream();
                while ((len = errorStream.read(data)) != -1) {
                    result.append(new String(data, 0, len, "GBK"));
                }
            } else {
                result.delete(0, result.length()).append("success");
                logger.info("result:{}", result);
            }
            return result.toString();
        } catch (Exception e) {
            logger.info("error:{}", e.getMessage());
            return "error:" + e.getMessage();
        }
    }

    /**
     * 数据恢复操作工具
     */
    public static String dbRestore(String fileName) {
        String filePath = backPath + fileName;
        logger.info("待还原sql文件:{}",filePath);
        StringBuilder restoreCmd = new StringBuilder();
        restoreCmd.append(toolPath + "mysql");
        restoreCmd.append(" -h" + host);
        restoreCmd.append(" -u" + username);
        restoreCmd.append(" -p" + password);
        restoreCmd.append(" < ");
        restoreCmd.append(filePath);
        logger.info("cmd命令为：" + restoreCmd.toString());
        logger.info("开始还原数据");
        String[] cmd = {"sh", "-c", restoreCmd.toString()};
        return exec(cmd);
    }

    /**
     * 删除数据备份
     */
    public static String remove(String fileName) {
//        String file = DBConstants.backPath + fileName;
        String file = fileName;
        logger.info("待删除sql文件:{}",file);
        File del_file = new File(file);
        if (del_file.isFile()) {
            if (!del_file.delete()) {
                logger.info("删除失败");
                return "delete failed";
            }
        }
        logger.info("删除成功");
        return "delete success";

    }
}
